<template>
  <main
    ref="mainContainer"
    class="main-container"
    v-loading="isLoading"
    :element-loading-text="loadingText"
  >
    <div class="main-content">
      <div class="search-bar">
        <div>
          <el-text>设备ID：</el-text>
          <el-select
            v-model="currentDeviceNode"
            class="device-select"
            filterable
            placeholder="请选择要查询的设备ID"
          >
            <el-option
              v-for="nodeId in nodeIds"
              :key="nodeId"
              :label="nodeId"
              :value="nodeId"
            ></el-option>
          </el-select>
        </div>
        <div>
          <el-button type="danger" :disabled="disableOperationButton" @click="onUploadToDevice">
            配置下发设备
          </el-button>
        </div>
      </div>
      <el-divider />
      <div class="table-content">
        <el-table style="width: 100%" :data="deviceConfigs">
          <el-table-column fixed prop="ipAddress" label="IpAddress" />
          <el-table-column prop="port" label="Port" />
          <el-table-column prop="deviceName" label="DeviceName" />
          <el-table-column prop="deviceType" label="DeviceType" />
          <el-table-column prop="slot" label="Slot" />
          <el-table-column prop="rack" label="Rack" />
          <el-table-column fixed="right" label="操作" width="120">
            <template #default="scope">
              <el-button link type="primary" size="small" @click="onDeleteConfig(scope.$index)">
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-button
          :disabled="disableOperationButton"
          class="mt-4"
          style="width: 100%"
          @click="showAddConfigDialog = true"
        >
          添加配置
        </el-button>
      </div>
    </div>
    <el-dialog
      v-model="showAddConfigDialog"
      title="添加新设备配置"
      width="400"
      :close-on-click-modal="false"
      draggable
      :show-close="true"
      :before-close="onDialogBeforeClose"
    >
      <div v-loading="dialogIsLoading" element-loading-text="正在添加设备节点配置...">
        <DeviceConfigItem
          style="margin: 10px"
          v-model:deviceName="deviceName"
          v-model:port="port"
          v-model:deviceType="deviceType"
          v-model:ipAddress="ipAddress"
          v-model:slot="slot"
          v-model:rack="rack"
        ></DeviceConfigItem>
        <div style="display: flex; justify-content: center; margin-top: 20px">
          <el-button type="primary" @click="onAddNewConfigAsync()">添加</el-button>
        </div>
      </div>
    </el-dialog>
  </main>
</template>

<script setup lang="ts">
import { ElMessage } from 'element-plus';
import { computed, onMounted, ref, watch } from 'vue';
import { DeviceServerClient } from '@/utils/device-server-client';
import type { DeviceConfig } from '@/types/Device';
import { DeviceTyeps } from '@/types/Device';
import DeviceConfigItem from './DeviceConfigItem.vue';
import { sleepAsync } from '@/utils/test-api';
import { showDeleteMessageBoxAsync } from '@/utils/message-box';

const deviceName = ref('');
const port = ref<number | null>(null);
const deviceType = ref<DeviceTyeps>(DeviceTyeps.SiemensS1500);
const ipAddress = ref('');
const slot = ref<number>(0);
const rack = ref<number>(0);
const dialogIsLoading = ref(false);

const disableOperationButton = computed(() => {
  return (
    currentDeviceNode.value == '' ||
    currentDeviceNode.value == null ||
    currentDeviceNode.value == undefined
  );
});

function onDialogBeforeClose(done: any) {
  if (dialogIsLoading.value) {
    ElMessage.info('正在添加新的设备配置...');
  }
  // 对话框正在加载时，不关闭对话框
  done(dialogIsLoading.value);
}

function resetProps() {
  deviceName.value = '';
  port.value = null;
  deviceType.value = DeviceTyeps.SiemensS1500;
  slot.value = 0;
  rack.value = 0;
}

const client = new DeviceServerClient(import.meta.env.VITE_DEVICE_SERVER_BASE_URL);
const isLoading = ref(false);
const currentDeviceNode = ref('');
const loadingText = ref('正在加载设备节点...');
const nodeIds = ref<string[]>([]);
const deviceConfigs = ref<DeviceConfig[]>([]);
const showAddConfigDialog = ref(false);

watch(currentDeviceNode, (newValue) => {
  if (newValue != null && newValue != '' && newValue != undefined) {
    reloadDeviceConfigsAsync(newValue);
  }
});

async function reloadDeviceIdsAsync() {
  loadingText.value = '正在加载设备节点...';
  isLoading.value = true;
  nodeIds.value = [];
  try {
    const result = await client.getIdsAsync();
    if (result.isSuccess) {
      if (result.result != null) {
        if (result.result.length == 0) {
          ElMessage.info('系统未添加设备节点！');
        }
        nodeIds.value = result.result ?? [];
      }
    } else {
      ElMessage.error(`加载设备节点错误,${result.message}`);
    }
  } catch (err) {
    ElMessage.error('加载设备节点错误！');
    console.error(err);
  } finally {
    isLoading.value = false;
  }
}

async function reloadDeviceConfigsAsync(nodeId: string) {
  loadingText.value = '正在加载设备节点配置...';
  isLoading.value = true;
  try {
    await sleepAsync(500);
    const result = await client.getDeviceConfigsAsync(nodeId);
    if (result.isSuccess) {
      deviceConfigs.value = result.result!;
    } else {
      ElMessage.error(`加载设备节点配置错误，${result.message}`);
    }
  } catch (err) {
    ElMessage.error('加载设备节点配置错误！');
    console.error(err);
  } finally {
    isLoading.value = false;
  }
}

async function onAddNewConfigAsync() {
  const reg = new RegExp('^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$');
  if (deviceName.value.length < 6) {
    ElMessage.error('设备逻辑名长度不能低于6个字符！');
  } else if (reg.test(ipAddress.value) == false) {
    ElMessage.error('IP 地址格式不正确！');
  } else if (port.value == null || port.value < 1 || port.value > 65535) {
    ElMessage.error('IP 端口无效（0~65535）！');
  } else {
    try {
      dialogIsLoading.value = true;
      await sleepAsync(500);
      // 插入设备节点
      const result = await client.insertDeviceConfigAsync({
        nodeId: currentDeviceNode.value,
        deviceName: deviceName.value,
        id: '',
        port: port.value,
        slot: slot.value,
        rack: rack.value,
        ipAddress: ipAddress.value,
        deviceType: deviceType.value
      });

      if (result.isSuccess) {
        // 重新刷新配置列表
        await reloadDeviceConfigsAsync(currentDeviceNode.value);
        // 重新初始化对象
        resetProps();
        ElMessage.success('成功添加新配置！');
        // 关闭对话框
        showAddConfigDialog.value = false;
      } else {
        ElMessage.error(result.message);
      }
    } catch (error) {
      console.error(error);
      ElMessage.error('添加配置时出现未知错误！');
    } finally {
      // 关闭对话框加载状态
      dialogIsLoading.value = false;
    }
  }
}

async function onDeleteConfig(index: number) {
  if (!(await showDeleteMessageBoxAsync())) {
    return;
  }

  const configuration = deviceConfigs.value[index];
  isLoading.value = true;
  loadingText.value = '正在删除设备节点配置...';
  try {
    await sleepAsync(500);
    const result = await client.deleteDeviceConfigAsync(configuration.id!);
    if (result.isSuccess) {
      ElMessage.success('删除配置成功！');
      await reloadDeviceConfigsAsync(currentDeviceNode.value);
    } else {
      ElMessage.error(result.message);
    }
  } catch (err) {
    console.error(err);
    ElMessage.error('删除配置时出现未知错误！');
  } finally {
    isLoading.value = false;
  }
}

// 配置下发设备
async function onUploadToDevice() {
  if (!(await showDeleteMessageBoxAsync())) {
    return;
  }

  if (deviceConfigs.value.length == 0) {
    ElMessage.error('该设备 ID 没有任何配置！');
  } else {
    loadingText.value = '正在下发配置设备...';
    isLoading.value = true;
    try {
      await sleepAsync(500);
      const result = await client.configAsync({
        deviceId: currentDeviceNode.value,
        task: {
          deviceConfigs: deviceConfigs.value
        }
      });

      if (result.isSuccess) {
        ElMessage.success('配置下发设备成功！');
      } else {
        ElMessage.error(result.message);
      }
    } catch (err) {
      console.error(err);
      ElMessage.error('配置下发设备时出现未知错误！');
    } finally {
      isLoading.value = false;
    }
  }
}

onMounted(() => {
  reloadDeviceIdsAsync();
});
</script>

<style lang="scss" scoped>
:deep(.el-divider--horizontal) {
  margin: 15px 0px 0px 0px;
}

.main-container {
  height: 100%;
  width: 100%;
  padding: 0px 15px 15px;

  .main-content {
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;

    .search-bar {
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: space-between;

      .device-select {
        width: 240px;
        margin-left: 10px;
      }
    }

    .table-content {
      flex-grow: 1;
    }
  }
}
</style>